/**
 * 2017年12月29日
 */
package com.gitee.weixin.mp.handler.msg.text;

import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * 猜大小游戏
 *
 * @author aaron 2017年12月29日
 */
@Component
public class GuessNumberTransaction extends AbstractTxTransaction {
    public static final String SESSION_KEY_GUESSNUMBER = "GuessNumberTransaction.SESSION_KEY_GUESSNUMBER";
    public static final String REIDS_KEY_NAME          = "GuessNumberTransaction.openid.caiCount.map";
    public static final String SESSIONID               = "sessionid";
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @PostConstruct
    public void init() {
        List<String> parttens = new ArrayList<>();
        parttens.add("猜大小");
        parttens.add("caiping");
        // parttens.add("caiping"); 可以是正则表达式

        this.setRegexStr(parttens);

        logger.info("###### {} init success.", this);
    }

    @Override
    public WxMpXmlOutMessage doTextTrans(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService,
                                         WxSessionManager sessionManager) {
        String content = "";

        // 设置session
        WxSession session = sessionManager.getSession(wxMessage.getFromUser());
        session.setAttribute(SESSION_KEY_TXTRANSACTION, this);
        // 设置一个区别于openid的sessionid
        String sessionId = (String) session.getAttribute(SESSIONID);
        if (sessionId == null) {
            sessionId = String.valueOf(System.currentTimeMillis());
            session.setAttribute(SESSIONID, sessionId);
        }


        Object number = session.getAttribute(SESSION_KEY_GUESSNUMBER);

        if (number != null) {
            int num = ((Integer) number).intValue();
            int newNum = 0;
            try {
                String hashKey = wxMessage.getFromUser() + sessionId;
                Object caiCount = stringRedisTemplate.opsForHash().get(REIDS_KEY_NAME, hashKey);
                int count = 1;
                if (caiCount != null) {
                    count = Integer.parseInt(String.valueOf(caiCount));
                    count++;
                }
                stringRedisTemplate.opsForHash().put(REIDS_KEY_NAME, hashKey, String.valueOf(count));

                newNum = Integer.valueOf(wxMessage.getContent());
                if (newNum > num) {
                    content = "您输入的数字太大啦";
                } else if (newNum < num) {
                    content = "您输入的数字太小啦";
                } else {
                    // 获取统计数据
                    Set<Map.Entry<Object, Object>> entries = stringRedisTemplate.opsForHash().entries(REIDS_KEY_NAME).entrySet();
                    OptionalInt min = entries.stream().mapToInt(e -> Integer.parseInt(String.valueOf(e.getValue()))).min();
                    OptionalDouble average = entries.stream().mapToInt(e -> Integer.parseInt(String.valueOf(e.getValue()))).average();
                    int uCount = entries.size();
                    content = "恭喜您答对了！共%s人玩过这个游戏，平均%s次完成游戏，最快的用了%s次，您用了%s次。继续玩一下吧？请输入：猜大小";
                    content = String.format(content, uCount, average.getAsDouble(), min.getAsInt(), count);

                    session.invalidate();
                }

            } catch (NumberFormatException e) {
                content = "您输入的不是数字";
            }


        } else {
            content = "很有挑战哦, 请输入一个100以内的整数";
            int newNum = RandomUtils.nextInt(1, 100);
            session.setAttribute(SESSION_KEY_GUESSNUMBER, newNum);
        }

        WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().toUser(wxMessage.getFromUser()).content(content).build();
        try {
            wxMpService.getKefuService().sendKefuMessage(kefuMessage);
        } catch (WxErrorException e) {
            logger.error(e.getError().getJson(), e);
        }

        return null;
    }

}
